Skip to content

fix(wsen-hids): Restore sensor config after power cycle.#240

Merged
nedseb merged 4 commits intomainfrom
fix/wsen-hids-power-cycle
Mar 25, 2026
Merged

fix(wsen-hids): Restore sensor config after power cycle.#240
nedseb merged 4 commits intomainfrom
fix/wsen-hids-power-cycle

Conversation

@nedseb
Copy link
Copy Markdown
Contributor

@nedseb nedseb commented Mar 25, 2026

Summary

Fix one-shot measurement timeout after a power_off() / power_on() cycle.

Root cause

power_on() only set the PD bit in CTRL_1 but did not restore the sensor configuration (averaging, BDU, calibration). After power_off(), these settings are lost, so the sensor was electrically powered but not properly configured for measurements.

Fix

  • Save init parameters (avg_t, avg_h, bdu) as instance attributes
  • power_on() now restores averaging, BDU, and calibration after setting the PD bit

Tests added

  • Power on restores averaging config (mock)
  • Power on restores BDU setting (mock)
  • Read one-shot works after power cycle (mock)

Hardware validation

--- Test: read_one_shot after power cycle ---
  Cycle 1: humidity=51.85 %RH, temperature=27.46 C
  Cycle 2: humidity=37.19 %RH, temperature=27.48 C
  Cycle 3: humidity=35.99 %RH, temperature=27.39 C
  Cycle 4: humidity=36.30 %RH, temperature=27.45 C
  Cycle 5: humidity=36.54 %RH, temperature=27.37 C

PASS: 5 power cycles completed without timeout

Closes #238

Copilot AI review requested due to automatic review settings March 25, 2026 11:08
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3f42ec46dd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +207 to +209
self.set_average(self._avg_t, self._avg_h)
if self._bdu:
self.enable_bdu(True)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve runtime config before restoring in power_on

power_on() now reapplies self._avg_t, self._avg_h, and self._bdu, but those fields are only initialized in __init__ and never updated by set_average()/enable_bdu(). After a caller changes averaging or BDU at runtime, a power_off()/power_on() cycle silently reverts to constructor-time settings (for example, enable_bdu(False) can be undone if the instance was created with enable_bdu=True), so the driver mutates user-selected configuration unexpectedly.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes WSEN-HIDS one-shot measurement timeouts after a power_off() / power_on() cycle by reapplying sensor configuration that is lost across power-down.

Changes:

  • Persist initial averaging/BDU settings on the driver instance and reapply them in power_on().
  • Re-read calibration data on power_on() to restore conversion parameters after a power cycle.
  • Add mock scenario tests intended to validate config restoration and post-cycle one-shot reads.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
lib/wsen-hids/wsen_hids/device.py Store init config and restore averaging/BDU/calibration during power_on() to recover correct sensor state after power cycling.
tests/scenarios/wsen_hids.yaml Add mock scenario tests for averaging/BDU restoration and one-shot reads after a power cycle.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 206 to +210
self._write_reg(REG_CTRL_1, ctrl1)
self.set_average(self._avg_t, self._avg_h)
if self._bdu:
self.enable_bdu(True)
self._read_calibration()
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

power_on() now restores averaging/BDU using _avg_t/_avg_h/_bdu, but those attributes are only set once in __init__. If a user calls set_average(...) or enable_bdu(False/True) after initialization, a later power_on() will restore the initial settings (and can even re-enable BDU after it was disabled). Consider updating _avg_t/_avg_h inside set_average() and _bdu inside enable_bdu(), and have power_on() apply enable_bdu(self._bdu) (both enable and disable) to reflect the current configuration.

Copilot uses AI. Check for mistakes.
Comment thread tests/scenarios/wsen_hids.yaml Outdated
Comment on lines +113 to +115
dev.power_on()
av_conf = i2c.readfrom_mem(dev.address, 0x10, 1)[0]
result = av_conf != 0
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test doesn't currently validate the new behavior: with FakeI2C, power_off() only clears the PD bit and does not reset AV_CONF, so av_conf will remain whatever was written during __init__ even if power_on() didn’t restore it. To make this meaningful, either (a) simulate a power-cycle reset by explicitly clobbering AV_CONF (e.g., write 0x00) after power_off() before calling power_on(), or (b) assert that power_on() performed a write to REG_AV_CONF via i2c.clear_write_log() / i2c.get_write_log(). Also, asserting av_conf == 0x1B (per the scenario’s mock_registers comment) is stronger than != 0.

Suggested change
dev.power_on()
av_conf = i2c.readfrom_mem(dev.address, 0x10, 1)[0]
result = av_conf != 0
# Simulate power-cycle reset of AV_CONF
i2c.writeto_mem(dev.address, 0x10, bytes([0x00]))
dev.power_on()
av_conf = i2c.readfrom_mem(dev.address, 0x10, 1)[0]
# Expect AVG_T=16, AVG_H=16 -> 0x1B as per mock_registers
result = av_conf == 0x1B

Copilot uses AI. Check for mistakes.
Comment thread tests/scenarios/wsen_hids.yaml Outdated
Comment on lines +119 to +127
- name: "Power on restores BDU setting"
action: script
script: |
dev.power_off()
dev.power_on()
ctrl1 = i2c.readfrom_mem(dev.address, 0x20, 1)[0]
result = (ctrl1 & 0x04) != 0
expect_true: true
mode: [mock]
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the averaging test, this will pass even if power_on() never restores BDU because the mock starts with CTRL_1=0x04 and power_off() doesn’t clear the BDU bit in FakeI2C. To ensure the test actually covers the fix, simulate register loss after power_off() (e.g., overwrite CTRL_1 to 0x00) before power_on(), or assert that power_on() wrote the BDU bit back by inspecting i2c.get_write_log().

Copilot uses AI. Check for mistakes.
Comment thread tests/scenarios/wsen_hids.yaml Outdated
Comment on lines +129 to +137
- name: "Read one-shot works after power cycle"
action: script
script: |
dev.power_off()
dev.power_on()
h, t = dev.read_one_shot()
result = isinstance(h, float) and isinstance(t, float)
expect_true: true
mode: [mock]
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As written, this likely passes even on the pre-fix implementation because the mock STATUS register is hardcoded to “data ready” and power_off() doesn’t invalidate calibration/config in FakeI2C. To make it exercise the power-cycle regression, consider simulating lost state (e.g., clear dev._calibration and/or clobber key config registers after power_off()) and then assert power_on() repopulates calibration/config before read_one_shot() succeeds (or assert the expected configuration writes occurred using i2c.get_write_log()).

Copilot uses AI. Check for mistakes.
@steamicc steamicc deleted a comment from chatgpt-codex-connector Bot Mar 25, 2026
@nedseb
Copy link
Copy Markdown
Contributor Author

nedseb commented Mar 25, 2026

All 5 review comments addressed in 8066562:

  1. Runtime config syncset_average() and enable_bdu() now update _avg_t/_avg_h/_bdu so power_on() restores the current config, not just the constructor defaults.

  2. Mock tests simulate register loss — All 3 mock tests now clobber registers (write 0x00) after power_off() before calling power_on(), ensuring the tests actually exercise the restore logic.

  3. New test for runtime changes — Added "Power on preserves runtime config changes" which disables BDU at runtime, power-cycles, and verifies BDU stays disabled.

@nedseb nedseb added the bug Something isn't working label Mar 25, 2026
@nedseb nedseb merged commit 56e5d39 into main Mar 25, 2026
3 checks passed
@nedseb nedseb deleted the fix/wsen-hids-power-cycle branch March 25, 2026 11:47
semantic-release-updater Bot pushed a commit that referenced this pull request Mar 25, 2026
## [0.0.3](v0.0.2...v0.0.3) (2026-03-25)

### Bug Fixes

* **wsen-hids:** Restore sensor config after power cycle. ([#240](#240)) ([56e5d39](56e5d39))
@semantic-release-updater
Copy link
Copy Markdown

🎉 This PR is included in version 0.0.3 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

wsen_hids: one-shot measurement timeout after power cycle

2 participants